package com.base.cn.platform.os.controller.mobile.share;

import com.base.cn.platform.os.common.MobileBaseController;
import com.base.cn.platform.os.common.constants.ConfigName;
import com.base.cn.platform.os.common.j2cache.CustomCacheChannel;
import com.base.cn.platform.os.common.j2cache.J2CacheRegion;
import com.base.cn.platform.os.common.utils.StringUtils;
import com.base.cn.platform.os.common.utils.http.HttpUtil;
import com.base.cn.platform.os.common.utils.result.ResultUtil;
import com.base.cn.platform.os.common.utils.web.thirdLogin.WXLoginUtils;
import com.base.cn.platform.os.service.manage.config.SysConfigService;
import com.google.gson.reflect.TypeToken;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import java.io.IOException;
import java.security.MessageDigest;
import java.util.*;

/**
 * 分享Controller
 *
 * @author s.li
 * @date 2018/11/01
 */
@Controller
@RequestMapping("/mobile/share")
@Slf4j
public class MobileShareController extends MobileBaseController {

    @Autowired
    private SysConfigService sysConfigService;
    @Autowired
    private CustomCacheChannel customCacheChannel;

    /**
     * 获取微信分享签名
     * @param url 为调用页面的完整 url
     */
    @RequestMapping("/WeChatSignature")
    @ResponseBody
    public Map<String, Object> WeChatSignature(String url)throws IOException {
        TreeMap<String, String> sysConfigContext = sysConfigService.getSysConfigContext(ConfigName.WXLOGIN);

        String nonce_str = create_nonce_str();//32位随机数
        String timestamp = create_timestamp();//时间戳
        //微信公众号的appid
        String  appId = sysConfigContext.get("appId");
        //微信公众号的secret
        String secret =sysConfigContext.get("appSecret");
        String jsapi_ticket = (String) customCacheChannel.get(J2CacheRegion.TWO_HOURS_REGION.getValue(), "wx_share_jsapi_ticket").getValue();
        if(StringUtils.isEmpty(jsapi_ticket)){
            jsapi_ticket = this.getJsApiTicket(appId,secret);
        }
        if(StringUtils.isEmpty(jsapi_ticket)){
            return ResultUtil.ERROR("微信配置错误，获取分享内容失败");
        }
        //获取签名
        String signature = getSign(jsapi_ticket,nonce_str,timestamp,url);
        //设置返回参数Map
        Map<String, String> result = new HashMap<>();
        result.put("url", url);
        result.put("nonceStr", nonce_str); //生成签名的随机串
        result.put("timestamp", timestamp); //生成签名的时间戳
        result.put("signature", signature);//签名
        result.put("appId",appId);
        return ResultUtil.SUCCESS("获取成功",result);
    }

    /**
     * 获取微信jsapi_ticket 的有效期为 7200 秒
     * @param appId  微信公众号APPID
     * @param appSecret  微信公众号AppSecret
     * @return 返回微信的JsApiTicket
     */
    private  String getJsApiTicket(String appId, String appSecret)throws IOException {
        //获取公众号的 AccessToken
        String accessToken = WXLoginUtils.getOpenAccessToken(appId,appSecret,customCacheChannel);
        if(StringUtils.isNotEmpty(accessToken)){
            // 获取公众号ticket的链接
            String requestUrl = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?type=jsapi&access_token="+accessToken;
            //获取JsApiTicket
            String result = HttpUtil.doPost(requestUrl, null);
            Map<String, String> map = gson.fromJson(result, new TypeToken<Map<String, Object>>() {}.getType());
            log.info("===微信分享JsApiTicket==="+map.toString());
            // 如果请求成功
            if (!map.isEmpty()) {
                String ticket = map.get("ticket");
                customCacheChannel.set(J2CacheRegion.TWO_HOURS_REGION.getValue(),"wx_share_jsapi_ticket",ticket);
                return ticket;
            }
        }
        return null;
    }

    /**
     * 获取签名
     * @param jsapi_ticket
     * @param nonce_str 32位随机数据
     * @param timestamp 时间戳
     * @param url 分享的URL
     * @return SHA1加密后的签名
     */
    private String getSign(String jsapi_ticket,String nonce_str,String timestamp,String url){
        TreeMap<String,String> signMap = new TreeMap<>();
        signMap.put("jsapi_ticket",jsapi_ticket);
        signMap.put("noncestr",nonce_str);
        signMap.put("timestamp",timestamp);
        signMap.put("url",url);
        StringBuffer stringBuffer = new StringBuffer();
        //注意这里参数名必须全部小写，且必须有序
        signMap.forEach((k,v)->{
            stringBuffer.append(k).append("=").append(v).append("&");
        });
        //去掉前后&号
        String string1 = StringUtils.subHeadTailString(stringBuffer.toString(),"&");
        log.info("-------------------------------加密前string1："+string1);
        String signature = null;
        try{
            MessageDigest crypt = MessageDigest.getInstance("SHA-1");
            crypt.reset();
            crypt.update(string1.getBytes("UTF-8"));
            signature = byteToHex(crypt.digest());
        }catch (Exception e){
            log.error("分享加密错误，sign()--error",e);
        }
        log.info("-------------------------------加密后signature："+signature);
        return signature;
    }

    private  String byteToHex(final byte[] hash) {
        Formatter formatter = new Formatter();
        for (byte b : hash){
            formatter.format("%02x", b);
        }
        String result = formatter.toString();
        formatter.close();
        return result;
    }

    private  String create_nonce_str() {
        return UUID.randomUUID().toString();
    }

    private  String create_timestamp() {
        return Long.toString(System.currentTimeMillis() / 1000);
    }

}
